// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include "CalcManager\UnitConverter.h"
#include "Common/NavCategory.h"

namespace CalculatorApp
{
    namespace ViewModel
    {
        struct OrderedUnit : UnitConversionManager::Unit
        {
            OrderedUnit(){}

            OrderedUnit(int id, std::wstring name, std::wstring abbreviation, int order, bool isConversionSource = false, bool isConversionTarget = false, bool isWhimsical = false)
                : UnitConversionManager::Unit(id, name, abbreviation, isConversionSource, isConversionTarget, isWhimsical), order(order)
            {
            }

            int order;
        };

        struct UnitData
        {
            CalculatorApp::Common::ViewMode categoryId;
            int unitId;
            double factor;
        };

        struct ExplicitUnitConversionData : UnitConversionManager::ConversionData
        {
            ExplicitUnitConversionData(){}
            ExplicitUnitConversionData(CalculatorApp::Common::ViewMode categoryId, int parentUnitId, int unitId, double ratio, double offset, bool offsetFirst = false) :
                categoryId(categoryId), parentUnitId(parentUnitId), unitId(unitId), UnitConversionManager::ConversionData(ratio, offset, offsetFirst)
            {

            }

            CalculatorApp::Common::ViewMode categoryId;
            int parentUnitId;
            int unitId;
        };

        class UnitConverterDataLoader : public UnitConversionManager::IConverterDataLoader,
            public std::enable_shared_from_this<UnitConverterDataLoader>
        {
        public:
            UnitConverterDataLoader(Windows::Globalization::GeographicRegion^ region);

        private:
            // IConverterDataLoader
            void LoadData() override;
            std::vector<UnitConversionManager::Category> LoadOrderedCategories() override;
            std::vector<UnitConversionManager::Unit> LoadOrderedUnits(const UnitConversionManager::Category& c) override;
            std::unordered_map<UnitConversionManager::Unit, UnitConversionManager::ConversionData, UnitConversionManager::UnitHash> LoadOrderedRatios(const UnitConversionManager::Unit& unit) override;
            bool SupportsCategory(const UnitConversionManager::Category& target) override;
            // IConverterDataLoader

            void GetCategories(_In_ std::shared_ptr<std::vector<UnitConversionManager::Category>> categoriesList);
            void GetUnits(_In_ std::unordered_map<CalculatorApp::Common::ViewMode, std::vector<CalculatorApp::ViewModel::OrderedUnit>>& unitMap);
            void GetConversionData(_In_ std::unordered_map<CalculatorApp::Common::ViewMode, std::unordered_map<int, double>>& categoryToUnitConversionMap);
            void GetExplicitConversionData(_In_ std::unordered_map<int, std::unordered_map<int, UnitConversionManager::ConversionData>>& unitToUnitConversionList);

            std::wstring GetLocalizedStringName(_In_ Platform::String^ stringId);
            std::wstring GetRegion();

            std::shared_ptr<std::vector<UnitConversionManager::Category>> m_categoryList;
            std::shared_ptr<UnitConversionManager::CategoryToUnitVectorMap> m_categoryToUnits;
            std::shared_ptr<UnitConversionManager::UnitToUnitToConversionDataMap> m_ratioMap;
            Platform::String^ m_currentRegionCode;
        };
    }
}
